/*
**  Copyright (c) 2014 Michael Liu(michael.liu.point@gmail.com).
**
**  Project: Gateway Unified Management Platform
**  File:    dbopt.c
**  Author:  Michael
**  Date:    03/20/2014
**
**  Purpose:
**    db operation related implement.
*/

/* Include files. */

#include "dbopt.h"

/* Macro constant definitions. */

/* Type definitions. */

/* Local function declarations. */

static void *key_of_record(void *data_p);
static void *create_record(void *data_p);
static void free_record(void *data_p);
static void *copy_record(void *dest_data_p, void *src_data_p);
static void *memory_alloc(size_t size);
static void memory_free(void *ptr);

/* Macro API definitions. */

#define check_table(table_p) \
do                                                                    \
{                                                                     \
    if (table_p == NULL)                                              \
    {                                                                 \
        sysmgr_err("Null pointer detected.\n");                        \
        return (eRET_INVALID_STATE);                                  \
    }                                                                 \
} while(0)

/* Global variable declarations. */

int generate_unsigned_int_index_cmp(void *record_a, void *record_b, void *cmp_param)
{
	unsigned int *record_a_id = (unsigned int *)record_a;
	unsigned int *record_b_id = (unsigned int *)record_b;

	return ((*record_a_id) - (*record_b_id));
}

e_ret db_table_init(TAVL_treeptr * table_pp, record_cmp_func compare, void *param)
{

	TAVL_treeptr tree_p;

	check_table(table_pp);

	tree_p =
	    tavl_init(compare, key_of_record, create_record, free_record, copy_record, (void *)memory_alloc,
		      memory_free, param);
	if (tree_p == NULL) {
		sysmgr_err("tavl_init() failed.\n");
		return (eRET_NO_RESOURCE);
	}

	*table_pp = tree_p;

	return (eRET_SUCCESS);

}				/* End of db_table_init() */

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
e_ret db_table_add_record(TAVL_treeptr table_p, void *record, unsigned int size)
{

	TAVL_nodeptr return_p;
	void *new_node_p;

	check_table(table_p);

	new_node_p = memory_alloc(size);
	if (new_node_p == NULL) {
		return (eRET_NO_RESOURCE);
	}

	memcpy(new_node_p, record, size);

	return_p = tavl_insert(table_p, new_node_p, NO_REPLACE);
	if (return_p == NULL) {
		return (eRET_NO_RESOURCE);
	} else if (tavl_node_data(return_p) != new_node_p) {
		return (eRET_ALREADY_EXIST);
	}

	return (eRET_SUCCESS);

}				/* End of db_table_add_record() */

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
e_ret db_table_del_record(TAVL_treeptr table_p, void *record_p)
{

	void *return_p;

	return_p = tavl_delete(table_p, record_p);
	if (return_p == NULL) {
		return (eRET_NOT_EXIST);
	}

	free(return_p);

	return (eRET_SUCCESS);

}

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
e_ret db_table_search_record(TAVL_treeptr table_p, void *record_p, unsigned int size)
{

	TAVL_nodeptr return_p;

	return_p = tavl_find(table_p, record_p);

	if (return_p == NULL) {
		return (eRET_NOT_EXIST);
	}

	if (tavl_node_data(return_p) == NULL) {
		sysmgr_err("NULL list node data pointer!!!\n");
		return (eRET_FAILURE);
	}

	memcpy(record_p, tavl_node_data(return_p), size);

	return (eRET_SUCCESS);

}				/* End of db_table_search_record() */

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
e_ret db_table_update_record(TAVL_treeptr table_p, void *record_p, unsigned int size)
{

	TAVL_nodeptr return_p;

	return_p = tavl_find(table_p, record_p);

	if (return_p == NULL) {
		return (eRET_NOT_EXIST);
	}

	if (tavl_node_data(return_p) == NULL) {
		sysmgr_err("NULL list node data pointer!!!\n");
		return (eRET_FAILURE);
	}

	memcpy(tavl_node_data(return_p), record_p, size);

	return (eRET_SUCCESS);

}				/* End of db_table_update_record() */

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
e_ret db_table_first_record(TAVL_treeptr table_p, void *record_p, unsigned int size)
{

	TAVL_nodeptr return_p;

	return_p = tavl_succ(tavl_reset(table_p));
	if (return_p == NULL) {
		return (eRET_NOT_EXIST);
	}

	if (tavl_node_data(return_p) == NULL) {
		sysmgr_err("NULL list node data pointer!!!\n");
		return (eRET_FAILURE);
	}

	memcpy(record_p, tavl_node_data(return_p), size);

	return (eRET_SUCCESS);
}				/* End of db_table_first_record() */

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
e_ret db_table_next_record(TAVL_treeptr table_p, void *record_p, unsigned int size)
{

	TAVL_nodeptr return_p;
	TAVL_nodeptr current_p;

	current_p = tavl_find(table_p, record_p);
	if (current_p == NULL) {
		return (eRET_NOT_EXIST);
	}

	return_p = tavl_succ(current_p);
	if (return_p == NULL) {
		return (eRET_NOT_EXIST);
	}

	if (tavl_node_data(return_p) == NULL) {
		sysmgr_err("NULL list node data pointer!!!\n");
		return (eRET_FAILURE);
	}

	memcpy(record_p, tavl_node_data(return_p), size);

	return (eRET_SUCCESS);
}				/* End of db_table_next_record() */

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
e_ret db_table_clean(TAVL_treeptr table_p)
{

	check_table(table_p);

	tavl_destroy(table_p);

	return (eRET_SUCCESS);

}				/* End of db_table_clean() */

/*
** Note, we do not check input pointers, we do not keep locks,
** Do this, if you want when you invoke this function.
*/
int db_table_record_counter(TAVL_treeptr table_p)
{

	if (table_p == NULL) {
		sysmgr_err("Null pointer detected.\n");
		return (-1);
	}

	return (tavl_counter(table_p));

}				/* End of db_table_walk() */

/* Key(Id) of item. */
void *key_of_record(void *data_p)
{

	return (data_p);

}

/* Create item. */
void *create_record(void *data_p)
{

	/* Just return data pointer. */
	return (data_p);

}

/* Free Item. */
void free_record(void *data_p)
{

	/* Free memory. */
	memory_free(data_p);

}

/* Copy Item. No use now. */
void *copy_record(void *dest_data_p, void *src_data_p)
{

	return (src_data_p);

}

/* memory allocator function. */
void *memory_alloc(size_t size)
{
	return malloc(size);
}

/* memory free function. */
void memory_free(void *ptr)
{

	if (ptr != NULL) {
		free(ptr);
	}
}
